#include "bsp_uart.h"
#include "usart.h"
#include "main.h"
#include "string.h"
#include "stdlib.h"

#include "FreeRTOS.h"
#include "cmsis_os.h"
#include "queue.h"

#include "RC_receive.h"
/* 遥控器接收重写（未完成） */

uint8_t dbus_buf[DBUS_BUFLEN];

/**
  * @brief      enable global uart it and do not use DMA transfer done it
  * @param[in]  huart: uart IRQHandler id
  * @param[in]  pData: receive buff 
  * @param[in]  Size:  buff size
  * @retval     set success or fail
  */
static int uart_receive_dma_no_it(UART_HandleTypeDef* huart, uint8_t* pData, uint32_t Size)
{
  uint32_t tmp1 = 0;

  tmp1 = huart->RxState;
	
	if (tmp1 == HAL_UART_STATE_READY)	//当uart准备就绪时
	{
		if ((pData == NULL) || (Size == 0))
		{
			return HAL_ERROR;
		}

		huart->pRxBuffPtr = pData;	//设置接收缓冲区
		huart->RxXferSize = Size;	//设置缓冲区大小
		huart->ErrorCode  = HAL_UART_ERROR_NONE;	//设置错误标志位

		/* Enable the DMA Stream */
		/* 使能DMA数据流 */
		HAL_DMA_Start(huart->hdmarx, (uint32_t)&huart->Instance->DR, (uint32_t)pData, Size);

		/* 
		 * Enable the DMA transfer for the receiver request by setting the DMAR bit
		 * in the UART CR3 register 
		 */
		
		/*
		 * 通过设置DMAR位，为接收方请求启用DMA传输
		 * 在UART CR3寄存器
		 */
		SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);	//使能DMA接收器

		return HAL_OK;
	}
	else
	{
		return HAL_BUSY;
	}
}

/**
  * @brief      returns the number of remaining data units in the current DMAy Streamx transfer.
  * @param[in]  dma_stream: where y can be 1 or 2 to select the DMA and x can be 0
  *             to 7 to select the DMA Stream.
  * @retval     The number of remaining data units in the current DMAy Streamx transfer.
  */
uint16_t dma_current_data_counter(DMA_Stream_TypeDef *dma_stream)
{
  /* Return the number of remaining data units for DMAy Streamx */
  return ((uint16_t)(dma_stream->NDTR));
}

/**
  * @brief      clear idle it flag after uart receive a frame data
  * @param[in]  huart: uart IRQHandler id
  * @retval  
  */
static void uart_rx_idle_callback(UART_HandleTypeDef* huart)
{
	/* clear idle it flag avoid idle interrupt all the time */
	__HAL_UART_CLEAR_IDLEFLAG(huart);

	/* handle received data in idle interrupt */
	if (huart == &DBUS_HUART)
	{
		/* clear DMA transfer complete flag */
		__HAL_DMA_DISABLE(huart->hdmarx);

		/* handle dbus data dbus_buf from DMA */
		if ((DBUS_MAX_LEN - dma_current_data_counter(huart->hdmarx->Instance)) == DBUS_BUFLEN)
		{
			sbus_to_rc(dbus_buf);
		}
		
		/* restart dma transmission */
		__HAL_DMA_SET_COUNTER(huart->hdmarx, DBUS_MAX_LEN);
		__HAL_DMA_ENABLE(huart->hdmarx);
	}
}

/**
  * @brief      callback this function when uart interrupt 
  * @param[in]  huart: uart IRQHandler id
  * @retval  
  */
void uart_receive_handler(UART_HandleTypeDef *huart)
{  
	if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) && 
			__HAL_UART_GET_IT_SOURCE(huart, UART_IT_IDLE))
	{
		uart_rx_idle_callback(huart);
	}
}

/**
  * @brief   initialize dbus uart device 
  * @param   
  * @retval  
  */
void dbus_uart_init(void)
{
	/* open uart idle it */
	/* 开启USART 空闲中断 */
	__HAL_UART_CLEAR_IDLEFLAG(&DBUS_HUART);	//清除中断标志位
	__HAL_UART_ENABLE_IT(&DBUS_HUART, UART_IT_IDLE);//使能空闲中断

	uart_receive_dma_no_it(&DBUS_HUART, dbus_buf, DBUS_MAX_LEN);
}

/* 裁判系统的接收 */

uint8_t usart6_rx_buff[USART6_RX_BUFF_SIZE];
//uint8_t usart6_rx_buff;
uint8_t usart6_rx_buf_pos = 0;	//USART6 本次回调接收的数据在缓冲区的起点
uint8_t usart6_rx_length = 0;	//USART6 本次回调接收数据的长度

extern osMessageQId RefereeQueueHandle;

/* HAL库重写的 usart*/
void bsp_usart_init(void)
{
	HAL_UARTEx_ReceiveToIdle_DMA(&huart6, usart6_rx_buff, sizeof(usart6_rx_buff));	//USART6 裁判系统串口 DMA空闲中断接收
		//HAL_UART_Receive_DMA(&huart6, &usart6_rx_buff, 1);//DMA传输
}

//void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
//{
//	if(huart->Instance == USART6)
//	{
//		xQueueSendFromISR(RefereeQueueHandle, &usart6_rx_buff, 0);
//		HAL_UART_Receive_DMA(&huart1, &usart6_rx_buff, 1);//DMA传输
//	}
//}

//接收中断函数 DMA空闲中断接收都在这里
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
	if(huart->Instance == USART6)
	{
		usart6_rx_length = Size - usart6_rx_buf_pos;
		
		for(int i = usart6_rx_buf_pos; i < usart6_rx_length; i++)
		{	
			//xQueueSendFromISR(RefereeQueueHandle, &usart6_rx_buff[i], 0);
		}
		
		usart6_rx_buf_pos += usart6_rx_length;
    
		if (usart6_rx_buf_pos >= (uint16_t)USART6_RX_BUFF_SIZE)
		{
			usart6_rx_buf_pos = 0;	//缓冲区用完后，返回 0 处重新开始
		}
	}
}
